package v1

import (
	"errors"
	"fmt"
	"gin-vben-admin/api/v1/errcode"
	"gin-vben-admin/internal/constant"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	"gorm.io/gorm"
	"net/http"
	"strings"
)

var validateTranslator ut.Translator

func init() {
	zhT := zh.New()
	enT := zh.New()
	uni := ut.New(enT, zhT)
	validateTranslator, _ = uni.GetTranslator("zh")
}

type Resp struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Result  any    `json:"result"`
}

type DataOption struct {
	Text   string          `json:"text"`   //显示文本
	Value  interface{}     `json:"value"`  //数据id
	Status constant.Status `json:"status"` //是否可选 ，1可选 2不可选
	Other  any             `json:"other"`  //其他
}

type DataOptions struct {
	Total   int64        `json:"total"`   //总数量
	Options []DataOption `json:"options"` //选项数据
}

type PageResult struct {
	Total int64 `json:"total"`
	Items any   `json:"items"`
}

func Success(ctx *gin.Context, data any) {
	if data == nil {
		data = gin.H{}
	}
	ctx.AbortWithStatusJSON(http.StatusOK, Resp{Code: 0, Message: "success", Result: data})
}

func PageData(ctx *gin.Context, total int64, items any, err error) {
	if err != nil {
		Error(ctx, err)
		return
	}
	if items == nil {
		items = make([]int, 0)
	}
	ctx.AbortWithStatusJSON(http.StatusOK, Resp{Code: 0, Message: "success", Result: PageResult{
		Total: total,
		Items: items,
	}})
}

func Error(ctx *gin.Context, err error, data ...any) {
	code := int(errcode.ErrServerError)
	if e, ok := err.(errcode.ErrCode); ok {
		code = int(e)
	} else if e, ok := err.(errcode.ErrWrap); ok {
		code = e.ErrCode()
	} else if e, ok := err.(validator.ValidationErrors); ok {
		fmt.Println("validator.ValidationErrors")
		_errs := make([]string, len(e))
		for i := range e {
			_errs[i] = e[i].Translate(validateTranslator)
		}
		code = int(errcode.ErrBadRequestParams)
		err = errors.New(strings.Join(_errs, ","))
	} else if errors.Is(err, gorm.ErrRecordNotFound) {
		code = int(errcode.ErrNotFound)
		err = errcode.ErrNotFound
	} else {
		fmt.Printf("code:%d,err:%s\n", code, err.Error())
		err = errcode.ErrServerError
	}
	ctx.AbortWithStatusJSON(http.StatusOK, Resp{Code: code, Message: err.Error(), Result: data})
}

func Response(ctx *gin.Context, err error, data any) {
	if err != nil {
		Error(ctx, err)
	} else {
		Success(ctx, data)
	}
}

func Failed(ctx *gin.Context, code int, err error) {
	ctx.AbortWithError(code, err)
}
